package com.ruoyi.system.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.ClientUtils;
import com.ruoyi.common.OrderNumUtil;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.app.*;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.mapper.app.*;
import com.ruoyi.system.service.CommunityService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
public class CommunityServiceImpl implements CommunityService {

    @Autowired
    CommunityMapper communityMapper;
    @Autowired
    ChargeOptionMapper chargeOptionMapper;
    @Autowired
    CardChargeOptionMapper cardChargeOptionMapper;
    @Autowired
    ConsumptionOptionMapper consumptionOptionMapper;
    @Autowired
    ComboMapper comboMapper;
    @Autowired
    DeviceMapper deviceMapper;
    @Autowired
    DeviceSpaceMapper deviceSpaceMapper;
    @Autowired
    PowerBillingMapper powerBillingMapper;
    @Autowired
    SysUserMapper sysUserMapper;
    @Autowired
    CommunityPartnerMapper communityPartnerMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    CommunityMemberMapper communityMemberMapper;
    @Autowired
    OrderChargeMapper orderChargeMapper;
    @Autowired
    OrderComboMapper orderComboMapper;
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    CardMapper cardMapper;
    @Autowired
    DeptWxInfoMapper deptWxInfoMapper;
    @Autowired
    SysDeptMapper sysDeptMapper;
    @Autowired
    RechargeOptionMapper rechargeOptionMapper;


    @Override
    public List<Map> getOperatorByName(String operatorName) {
        SysUser sysUser = new SysUser();
        sysUser.setUserName(operatorName);
        return sysUserMapper.getOperatorByName(sysUser);
    }

    @Override
    public List<Map> getPartnerByName(String partnerName) {
        SysUser sysUser = new SysUser();
        sysUser.setUserName(partnerName);
        return sysUserMapper.getPartnerByName(sysUser);

    }

    @Override
    public List<SysUser> getCommunityPartnerList(Long communityId) {

        return sysUserMapper.getCommunityPartnerList(communityId);
    }

    @Override
    public void addPartner(Long communityId, Long partnerId, Double ratio) {
        List<CommunityPartner> communityPartners = communityPartnerMapper.getListByCommunityId(communityId);
        Double ratioAll = 0D;
        for (CommunityPartner communityPartner : communityPartners) {
            if (communityPartner.getUserId().equals(partnerId)) {
                throw new ServiceException("本小区下已存在相同分账人！");
            }
            ratioAll += communityPartner.getRatio();
        }
        if (ratioAll + ratio > 0.99D) {
            throw new ServiceException("总分成比例不能大于99%");
        }
        CommunityPartner communityPartner = new CommunityPartner();
        communityPartner.setCommunityId(communityId);
        communityPartner.setUserId(partnerId);
        communityPartner.setRatio(ratio);
        communityPartnerMapper.insertSelective(communityPartner);
    }

    @Override
    public void delPartner(Long partnerId) {
        communityPartnerMapper.deleteByPrimaryKey(partnerId);
    }

    @Override
    public void setPartner(Long communityId, Long partnerId, Double ratio) {
        List<CommunityPartner> communityPartners = communityPartnerMapper.getListByCommunityId(communityId);
        Double ratioAll = 0D;

        for (CommunityPartner communityPartner : communityPartners) {
            if (!communityPartner.getUserId().equals(partnerId)) {
                ratioAll += communityPartner.getRatio();
            }
        }
        if (ratioAll + ratio > 0.99D) {
            throw new ServiceException("总分成比例不能大于99%");
        }
        CommunityPartner communityPartner = communityPartnerMapper.selectByCommunityIdUserId(communityId, partnerId);
        communityPartner.setRatio(ratio);
        communityPartnerMapper.updateByPrimaryKeySelective(communityPartner);
    }

    @Override
    public List<User> registerUserList(String userName, String phone) {
        return userMapper.registerUserList(userName, phone);
    }

    @Override
    public void registerUserDel(Long userId) {
        userMapper.deleteByPrimaryKey(userId);
        communityMemberMapper.delByUserId(userId);
        cardMapper.unBindByUserId(userId);
    }

    @Override
    public void userState(Long userId, Integer state) {
        User user = new User();
        user.setId(userId);
        user.setState(state);
        userMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    public void setUserPhone(Long userId, String phone) {
        User user = userMapper.selectByPrimaryKey(userId);
        if (!isMobile(phone)) {
            throw new ServiceException("手机号格式错误！");
        }
        User check = userMapper.selectUserByUserPhone(phone,user.getAppId());
        if (StringUtils.isNotNull(check)) {
            throw new ServiceException("该手机号已注册！");
        }


        user.setPhone(phone);
        userMapper.updateByPrimaryKeySelective(user);
    }

    /**
     *  * 手机号验证
     *  * @param str
     *  * @return 验证通过返回true
     *  
     */
    public static boolean isMobile(final String str) {
        Pattern p = null;
        Matcher m = null;
        boolean b = false;
        p = Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$");
        m = p.matcher(str);
        b = m.matches();
        return b;
    }

    @Override
    public List<Map> userList(Long communityId, String userName, String phone) {
        return userMapper.userList(communityId, userName, phone);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void userCharge(Long communityId, Long userId, Integer type, String value) {
        Community community = communityMapper.selectByPrimaryKey(communityId);
        User user = userMapper.selectByPrimaryKey(userId);

        CommunityMember communityMember = communityMemberMapper.selectByUser(userId, communityId);
        if (StringUtils.isNull(communityMember) && Float.parseFloat(value) < 0L) {
            throw new ServiceException("该用户不属于此小区，无法第一次减去金额或天数");
        }
        if (StringUtils.isNull(communityMember)) {
            communityMember = new CommunityMember();
            communityMember.setUserId(user.getId());
            communityMember.setUserName(user.getUsername());
            communityMember.setCommunityId(communityId);
            communityMember.setCommunityName(community.getCommunityName());
            communityMember.setCreateTime(new Date());
            communityMemberMapper.insertSelective(communityMember);
            communityMember = communityMemberMapper.selectByPrimaryKey(communityMember.getId());
        }
        //添加订单
        Order order = new Order();
        order.setUserId(user.getId());
        order.setUserName(user.getUsername());
        order.setUserPhone(user.getPhone());
        order.setCommunityId(community.getId());
        order.setCommunityName(community.getCommunityName());
        order.setOperatorId(community.getOperatorId());
        order.setOperatorName(community.getOperatorName());
        order.setOrderNo(OrderNumUtil.getOrderNum());
        order.setWxOrderNo("管理员充值,充值人员：" + SecurityUtils.getLoginUser().getUser().getUserName());
        order.setOrderType(type);
        order.setOrderState(1);
        order.setType(0);
        order.setCreateTime(new Date());
        order.setMoney(new BigDecimal(value));
        orderMapper.insertSelective(order);

        if (type == 1) {
            if (Double.parseDouble(value) <0 &&  (Double.parseDouble(value)+communityMember.getBalance().add(communityMember.getDiscountBalance()).doubleValue()) < 0) {
                throw new ServiceException("减去金额过大！");
            }

            OrderCharge orderCharge = new OrderCharge();
            orderCharge.setOrderId(order.getId());
            orderCharge.setBeforeMoney(communityMember.getBalance().add(communityMember.getDiscountBalance()));
            orderCharge.setAfterMoney(communityMember.getBalance().add(communityMember.getDiscountBalance()).add(new BigDecimal(value)));
            orderCharge.setChargeMoney(new BigDecimal("0"));
            orderCharge.setDiscountMoney(new BigDecimal(value));
            orderCharge.setChargeTime(new Date());

            if (Double.parseDouble(value) > 0) {
                communityMember.setDiscountBalance(communityMember.getDiscountBalance().add(new BigDecimal(value)));
            } else {
                if ((communityMember.getDiscountBalance().doubleValue() + Double.parseDouble(value)) > 0) {
                    communityMember.setDiscountBalance(communityMember.getDiscountBalance().add(new BigDecimal(value)));
                } else {
                    value =  communityMember.getDiscountBalance().add(new BigDecimal(value)).toString();
                    communityMember.setBalance(communityMember.getBalance().add(new BigDecimal(value)));
                    communityMember.setDiscountBalance(new BigDecimal("0"));
                }
            }

            communityMemberMapper.updateByPrimaryKeySelective(communityMember);
            orderChargeMapper.insertSelective(orderCharge);
        } else {
            order.setMoney(new BigDecimal("0"));
            OrderCombo orderCombo = new OrderCombo();
            orderCombo.setOrderId(order.getId());
            orderCombo.setComboTime(Integer.valueOf(value));
            if (communityMember.getIsBy() == 1) {
                if (communityMember.getByTime().getTime() > System.currentTimeMillis()) {
                    communityMember.setByTime(DateUtils.addDays(communityMember.getByTime(), orderCombo.getComboTime()));
                } else {
                    communityMember.setByTime(DateUtils.addDays(new Date(), orderCombo.getComboTime()));
                }
            } else {
                communityMember.setIsBy(1);
                communityMember.setByTime(DateUtils.addDays(new Date(), orderCombo.getComboTime()));
            }
            orderCombo.setExpireTime(communityMember.getByTime());
            orderCombo.setChargeTime(new Date());
            communityMemberMapper.updateByPrimaryKeySelective(communityMember);
            orderComboMapper.insertSelective(orderCombo);
            orderMapper.updateByPrimaryKeySelective(order);
        }

    }

    @Override
    public void userAddCommunity(String phone, Long communityId) {
        Community community = communityMapper.selectByPrimaryKey(communityId);
        if (community.getOperatorId() == null) {
            throw new ServiceException("小区未绑定运营商");
        }

        User user = userMapper.selectUserByUserPhone(phone,community.getAppId());
        if (user == null) {
            throw new ServiceException("用户不存在！");
        }
        CommunityMember communityMember = communityMemberMapper.selectByUser(user.getId(), communityId);
        if (communityMember != null) {
            throw new ServiceException("用户已加入小区！");
        }


        communityMember = new CommunityMember();
        if (community.getCommunityType() == 2) {
            communityMember.setIsBloc(1);
        }
        communityMember.setCommunityId(communityId);
        communityMember.setCommunityName(community.getCommunityName());
        communityMember.setUserId(user.getId());
        communityMember.setUserName(user.getUsername());
        communityMember.setCreateTime(new Date());
        communityMemberMapper.insertSelective(communityMember);

    }

    @Override
    public void addCommunity(Community community) {
        Community check = communityMapper.selectByName(community.getCommunityName());
        if (StringUtils.isNotNull(check)) {
            throw new ServiceException("小区名已存在！");
        }
        if (community.getOperatorId() != null) {
            community.setAppId(getAppId(community.getOperatorId()));
        }
        community.setCreateTime(new Date());
        communityMapper.insertSelective(community);
    }

    private String getAppId(Long operatorId){
        SysDept sysDept = sysDeptMapper.selectDeptById(sysUserMapper.selectUserById(operatorId).getDeptId());
        String[] longs = sysDept.getAncestors().split(",");
        if (longs.length > 2) {
            return deptWxInfoMapper.selectByPrimaryKey(Long.valueOf(longs[2])).getAppId();
        }
        return deptWxInfoMapper.selectByPrimaryKey(sysDept.getDeptId()).getAppId();
    }

    @Override
    public void delCommunity(Long id) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        Device device = new Device();
        device.setCommunityId(id);
        List<Device> devices = deviceMapper.deviceList(device);
        if (devices.size() > 0) {
            throw new ServiceException("小区下存在设备，无法删除！");
        }
        List<CommunityPartner> communityPartners = communityPartnerMapper.getListByCommunityId(id);
        if (communityPartners.size() > 0) {
            throw new ServiceException("小区下存在分账人，无法删除！");
        }
        List<CommunityMember> communityMembers = communityMemberMapper.balanceList(null, id);
        if (communityMembers.size() > 0) {
            throw new ServiceException("小区下存在用户，无法删除！");
        }
        if (sysUser.isAdmin()) {
            communityMapper.deleteByPrimaryKey(id);
            consumptionOptionMapper.delByCommunityId(id);
        } else {
            Community community = communityMapper.selectByPrimaryKey(id);
            if (StringUtils.isNotNull(community)) {
                if (community.getOperatorId().equals(sysUser.getUserId())) {
                    communityMapper.deleteByPrimaryKey(id);
                    consumptionOptionMapper.delByCommunityId(id);
                }
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void setCommunity(Community community) {
        Community check =  communityMapper.selectByPrimaryKey(community.getId());

        if (StringUtils.isNotNull(check) && !check.getId().equals(community.getId())) {
            throw new ServiceException("小区名已存在！");
        }
        if (community.getOperatorId() != null) {
            community.setAppId(getAppId(community.getOperatorId()));
        }
        if (StringUtils.isNotNull(check.getOperatorId()) && community.getOperatorId() != null && !check.getOperatorId().equals(community.getOperatorId())) {
            deviceMapper.updateOperator(community.getId(), community.getOperatorId(), community.getOperatorName(),community.getAppId());

        }
        deviceMapper.updateByCommunityId(community.getCommunityName(),community.getId());
        communityMapper.updateByPrimaryKeySelective(community);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void optionReset(JSONObject jsonObject) {
        List<ChargeOption> chargeOptions = jsonObject.getJSONArray("charge").toJavaList(ChargeOption.class);
        List<CardChargeOption> cardChargeOptions = jsonObject.getJSONArray("cardCharge").toJavaList(CardChargeOption.class);
        List<Combo> combos = jsonObject.getJSONArray("combo").toJavaList(Combo.class);
        List<ConsumptionOption> consumptionOptions = jsonObject.getJSONArray("time").toJavaList(ConsumptionOption.class);
        List<RechargeOption> rechargeOptions = jsonObject.getJSONArray("recharge").toJavaList(RechargeOption.class);
        consumptionOptionMapper.delByCommunityId(consumptionOptions.get(0).getCommunityId());
        consumptionOptionMapper.insertBatch(consumptionOptions);
        chargeOptionMapper.delByCommunityId(chargeOptions.get(0).getCommunityId());
        cardChargeOptionMapper.delByCommunityId(cardChargeOptions.get(0).getCommunityId());
        comboMapper.delByCommunityId(combos.get(0).getCommunityId());
        chargeOptionMapper.insertBatch(chargeOptions);
        cardChargeOptionMapper.insertBatch(cardChargeOptions);
        comboMapper.insertBatch(combos);
        rechargeOptionMapper.delByCommunity(rechargeOptions.get(0).getCommunityId());
        rechargeOptionMapper.insertBatch(rechargeOptions);
    }

    @Override
    public JSONObject optionGet(Long communityId) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("charge", chargeOptionMapper.getChargeList(communityId));
        jsonObject.put("cardCharge", cardChargeOptionMapper.getCardChargeList(communityId));
        jsonObject.put("combo", comboMapper.getComboList(communityId));
        jsonObject.put("time", consumptionOptionMapper.getTimeOption(communityId));
        jsonObject.put("recharge",rechargeOptionMapper.getList(communityId));
        return jsonObject;
    }

    @Override
    public List<Long> communityListIds(String phone, String cardNum, String deviceNum) {
        List<Long> users = userMapper.selectCommunityIdByPhone(phone);
        List<Long> cards = cardMapper.selectCommunityIdByCardNo(cardNum);
        List<Long> devices = deviceMapper.selectCommunityIdBydeviceNum(deviceNum);
        List<Long> longs = new ArrayList<>();
        longs.addAll(users);
        longs.addAll(cards);
        longs.addAll(devices);
        HashSet<Long> set = new HashSet<>(longs);
        //把List集合所有元素清空
        longs.clear();
        //把HashSet对象添加至List集合
        longs.addAll(set);
        return longs;
    }


    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<Community> communityList(Community community, List<Long> longs) {
        List<Community> communities = communityMapper.communityList(community, longs);
        for (Community community1 : communities) {
            Map<String, Long> map = communityMapper.selectDeviceAmount(community1.getId());
            community1.setNormalAmount(map.get("normal").intValue());
            community1.setForbiddenAmount(map.get("forbidden").intValue());
        }
        return communities;
    }

    @Override
    public List<ChargeOption> getChargeList(Long communityId) {
        return chargeOptionMapper.getChargeList(communityId);
    }

    @Override
    public void resetCharge(List<ChargeOption> chargeOptions) {
        chargeOptionMapper.delByCommunityId(chargeOptions.get(0).getCommunityId());
        chargeOptionMapper.insertBatch(chargeOptions);
    }

    @Override
    public List<CardChargeOption> getCardChargeList(Long communityId) {
        return cardChargeOptionMapper.getCardChargeList(communityId);
    }

    @Override
    public void resetCardCharge(List<CardChargeOption> cardChargeOptions) {

        cardChargeOptionMapper.delByCommunityId(cardChargeOptions.get(0).getCommunityId());
        cardChargeOptionMapper.insertBatch(cardChargeOptions);
    }

    @Override
    public List<Combo> getComboList(Long communityId) {
        return comboMapper.getComboList(communityId);
    }

    @Override
    public void resetCombo(List<Combo> combos) {
        comboMapper.delByCommunityId(combos.get(0).getCommunityId());
        comboMapper.insertBatch(combos);
    }

    @Override
    public List<ConsumptionOption> getTimeOption(Long communityId) {
        return consumptionOptionMapper.getTimeOption(communityId);
    }

    @Override
    public void resetTimeOption(List<ConsumptionOption> consumptionOptions) {
        consumptionOptionMapper.delByCommunityId(consumptionOptions.get(0).getCommunityId());
        consumptionOptionMapper.insertBatch(consumptionOptions);
    }


}
